package com.ship.control;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.validation.BindException;
import org.springframework.web.HttpSessionRequiredException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

import com.ship.common.SessionInfo;


/**
 * 会员后台管理表单控制器
 * @author wqf
 * @version  Nov 14, 2011 2:11:52 PM
 */
public abstract class AbstractAdminFormController extends SimpleFormController {

	
	public AbstractAdminFormController(){
		
	}

	/**
	 * 子类必须通过此方法获取AdminSessionInfo对象
	 * @param request
	 * @return
	 */
	public SessionInfo getSessionInfo(HttpServletRequest request){
		return authorizationCredit.getSessionInfo(request);
	}
	
	/**
	 * 获取请求操作参数
	 * @param request
	 * @return
	 */
	public final String getRequestAction(HttpServletRequest request){
		return (String)request.getAttribute("action");
	}
	
	
	/**
	 * 内置处理方法
	 */
	protected final ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
		throws Exception {
		
		String action=null; 
		
//		if(!authorizationCredit.signinValidateByAdmin(request)){
//			authorizationCredit.redirectSigninValidateFailViewByAdmin(request, response);
//			return null;
//		}


		//操作类型参数
		action = request.getParameter("action");
		
		if(action == null) action = "";
		request.setAttribute("action", action);
		
		
		// Form submission or new form to show?
		if (isFormSubmission(request)) {
			// Fetch form object from HTTP session, bind, validate, process submission.
			try {
				Object command = getCommand(request);
				ServletRequestDataBinder binder = bindAndValidate(request, command);
				BindException errors = new BindException(binder.getBindingResult());
				return processFormSubmission(request, response, command, errors);
			}
			catch (HttpSessionRequiredException ex) {
				// Cannot submit a session form if no form object is in the session.
				if (logger.isDebugEnabled()) {
					logger.debug("Invalid submit detected: " + ex.getMessage());
				}
				return handleInvalidSubmit(request, response);
			}
		}
		
		else {
			
			//return showNoSubmissionForm(request);
			return showNewForm(request, response);
			
		}
		
	}
	
	/**
	 * 内置处理方法
	 */
    protected final ModelAndView processFormSubmission(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors)
    	throws Exception{
    	
    	String action=this.getRequestAction(request);
    	
//		successUrl = request.getParameter("successUrl");
//		failUrl = request.getParameter("failUrl");
		
	    if(errors.hasErrors()){
	        if(logger.isDebugEnabled())
	            logger.error("Data binding errors: " + errors.getErrorCount());
	        
	        return processFail(request,response,errors);
	    }
	    else {
	    	
    		if(action.equalsIgnoreCase("add")){
    			addSubmit(request,response,command,errors);
	    	}
	    	else if(action.equalsIgnoreCase("modify")) {
	    		modifySubmit(request,response,command,errors);
	    	}
	    	else {
	    		submit(request,response,command,errors);
	    	}
    		if(errors.hasErrors()) {
    			return processFail(request,response,errors);
    		}
    		else {
    			logger.debug("No errors -> processing submit");
    			return processSuccess(request,response,errors);
    		}
	    }
    }
    
    /**
     * 内置方法
     */
	protected final Object formBackingObject(HttpServletRequest request) throws Exception {
		String action=this.getRequestAction(request);
		Object command = null;
		
		if(action.equalsIgnoreCase("add")){
			command = getCommandDataForAdd(request);
    	}
    	else if(action.equalsIgnoreCase("modify")) {
    		command = getCommandDataForModify(request);
    	}
    	else {
    		command = getCommandData(request);
    	}
		
		if(command == null)
			command = createCommand();
		
		return command;
	}
	
	/**
	 * 从SimpleFormController重写，但未做任何改动，目的为加final，使不能够再重写而破坏处理过�?
	 */
	protected final ModelAndView showForm(
			HttpServletRequest request, HttpServletResponse response, BindException errors)
			throws Exception {

		return showForm(request, response, errors, null);
	}
	
	/**
	 * 内置处理
	 * 处理表单类型转换
	 */
	protected final void initBinder(HttpServletRequest request, ServletRequestDataBinder binder)
    throws Exception {
		
		//日期处理
		DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
		CustomDateEditor dateEditor = new CustomDateEditor(fmt, true);
		binder.registerCustomEditor(Date.class, dateEditor);
		//枚举处理
		
		//Double处理
		binder.registerCustomEditor(Integer.class, null,new CustomNumberEditor(Integer.class, null, true));
        binder.registerCustomEditor(Long.class, null,new CustomNumberEditor(Long.class, null, true));
        binder.registerCustomEditor(Double.class, null,new CustomNumberEditor(Double.class, null, true));
        binder.registerCustomEditor(double.class, null,new CustomNumberEditor(Double.class, null, true));
        super.initBinder(request, binder);
	}
	
    /**
     * �?��操作过程，不指定请求参数action时执行�?
     * @param request
     * @param response
     * @param command
     * @param errors
     * @throws Exception
     */
	protected void submit(HttpServletRequest request,HttpServletResponse response,Object command,BindException errors)
		throws Exception{
		
	}
	
	/**
	 * 添加操作过程，由请求参数action=add指定�?
	 * @param request
	 * @param response
	 * @param command
	 * @param errors
	 * @throws Exception
	 */
	protected void addSubmit(HttpServletRequest request,HttpServletResponse response,Object command,BindException errors)
		throws Exception{
	
	}
	
	/**
	 * 修改操作过程，由请求参数action=modify指定�?
	 * @param request
	 * @param response
	 * @param command
	 * @param errors
	 * @throws Exception
	 */
	protected void modifySubmit(HttpServletRequest request,HttpServletResponse response,Object command,BindException errors)
		throws Exception{
	
	}
	
	/**
	 * 修改操作时，返回初始化的命令数据对象�?
	 * @param request
	 * @return
	 */
	protected Object getCommandDataForModify(HttpServletRequest request){
		return null;
	}
	
	/**
	 * 增加操作，返回初始化的命令数据对象�?
	 * @param request
	 * @return
	 */
	protected Object getCommandDataForAdd(HttpServletRequest request){
		return null;
	}
	
	/**
	 * �?��操作时，返回初始化的命令数据对象
	 * @param request
	 * @return
	 */
	protected Object getCommandData(HttpServletRequest request){
		return null;
	}
	
	/**
	 * 成功处理过程，可以进行重载自定义自己的处理过程�?
	 * @param request
	 * @param response
	 * @param errors
	 * @return
	 * @throws Exception
	 */
	protected ModelAndView processSuccess(HttpServletRequest request, HttpServletResponse response,BindException errors) 
		throws Exception {
		String successUrl = request.getParameter("successUrl");
		
		if(null!= successUrl && !successUrl.equals("")){
			response.sendRedirect(successUrl);
			return null;
		}
		else if(this.getSuccessView() != null && this.getSuccessView() != ""){
			return this.showForm(request, errors, this.getSuccessView());
		}
		else {
			return this.showForm(request,errors,this.getFormView());
		}
		
	}
	
	/**
	 * 失败处理过程，可以进行重载自定义自己的处理过程�?
	 * @param request
	 * @param response
	 * @param errors
	 * @return
	 * @throws Exception
	 */
	protected ModelAndView processFail(HttpServletRequest request, HttpServletResponse response,BindException errors)
		throws Exception {
		String failUrl = request.getParameter("failUrl");
		
		if(failUrl != null && failUrl != ""){
			response.sendRedirect(failUrl);
			return null;
		}
		else {
			if(this.failView != null && this.failView != "") {
				return this.showForm(request, errors, this.getFailView());
			}
			else {
				return this.showForm(request,errors,this.getFormView());
			}
			
		}
	}
	

	private AuthorizationCredit authorizationCredit; // 授权信任处理对象
	private String failView; //失败处理视图
	
		
	public void setAuthorizationCredit(AuthorizationCredit authorizationCredit) {
		this.authorizationCredit = authorizationCredit;
	}	

	public String getFailView() {
		return failView;
	}

	public void setFailView(String failView) {
		this.failView = failView;
	}

}
